﻿using System;
using System.Collections.Generic;
using OverStore.Runtime.PersistenceServiceProvider;
using OverStore.Runtime.ObjectRepository;

namespace OverStore.TutorialAsTest.UnitTest.Configuration.Mocks
{
    public class DefaultRegistryLocator : IPersistenceServiceProvider
    {
        private readonly Dictionary<Type, object> _Index = new Dictionary<Type, object>();

        public DefaultRegistryLocator AddRegistry<TInstance, TIdentifer>(IEntityRegistry<TInstance, TIdentifer> registry) where TInstance : class
        {
            if (registry == null)
                throw new ArgumentNullException("registry");
            _Index.Add(typeof(TInstance), registry);

            return this;
        }

        IEntityRegistry<TInstance, TIdentifier> GetRegistry<TInstance, TIdentifier>() where TInstance : class
        {
            return (IEntityRegistry<TInstance, TIdentifier>)_Index[typeof(TInstance)];
        }

        IRepository<TInstance> GetRepository<TInstance>() where TInstance : class
        {
            throw new NotImplementedException();
        }

        IEnumerable<IRepositoryBase> AllRepositories()
        {
            throw new NotImplementedException();
        }

        #region IPersistenceServiceProvider Members

        public bool Reload<TInstance>(TInstance instance)
            where TInstance : class
        {
            return GetRepository<TInstance>().Reload(instance);
        }

        public void Save<TInstance>(TInstance instance)
            where TInstance : class
        {
            GetRepository<TInstance>().Save(instance);
        }
        
        public void MarkAsDeleted<TInstance>(TInstance instance)
            where TInstance : class
        {
            GetRepository<TInstance>().MarkAsDeleted(instance);
        }

        public void MarkAsDirty<TInstance>(TInstance instance)
            where TInstance : class
        {
            GetRepository<TInstance>().MarkAsDirty(instance);
        }

        public void Add<TInstance>(TInstance instance)
            where TInstance : class
        {
            GetRepository<TInstance>().Add(instance);
        }

        public TInstance Attach<TInstance>(TInstance instance)
            where TInstance : class
        {
            return GetRepository<TInstance>().Attach(instance);
        }

        public TIdentifier GetIdentifier<TInstance, TIdentifier>(TInstance instance)
            where TInstance : class
        {
            return GetRegistry<TInstance, TIdentifier>().GetIdentifier(instance);
        }

        public void PutNewIdentifier<TInstance, TIdentifier>(TInstance instance, TIdentifier newIdentifier)
            where TInstance : class
        {
            GetRegistry<TInstance, TIdentifier>().PutNewIdentifier(instance, newIdentifier);
        }

        public TInstance GetInstance<TInstance, TIdentifier>(TIdentifier identifier)
            where TInstance : class
        {
            return GetRegistry<TInstance, TIdentifier>().GetInstance(identifier);
        }

        public TInstance GetInstanceOrDefault<TInstance, TIdentifier>(TIdentifier identifier)
            where TInstance : class
        {
            return GetRegistry<TInstance, TIdentifier>().GetInstanceOrDefault(identifier);
        }

        public TInstance GetInstance<TInstance, TIdentifier>(TIdentifier identifier, OverStore.Runtime.Storage.TypedRecord data)
            where TInstance : class
        {
            return GetRegistry<TInstance, TIdentifier>().GetInstance(identifier, data);
        }

        public IEnumerable<TItem> ExecuteObjectReader<TItem, TParameter>(TParameter parameter)
            where TItem : class
            where TParameter : class
        {
            return GetRepository<TItem>().ExecuteObjectReader<TParameter>(parameter);
        }

        public IEnumerable<TItem> ExecuteObjectReader<TItem>()
            where TItem : class
        {
            return GetRepository<TItem>().ExecuteObjectReader();
        }

        public void SaveAll()
        {
            foreach (var item in _Index.Values)
            {
                var rep = item as IRepositoryBase;
                if (rep != null)
                    rep.SaveAll();
            }
        }

        #endregion

        public void ReloadCollection<TInstance>(IEnumerable<TInstance> instance)
            where TInstance : class
        {
            throw new NotImplementedException();
        }

        public void ReloadCollection<TInstance, TParameter>(IEnumerable<TInstance> collection, TParameter parameter)
            where TInstance : class
            where TParameter : class
        {
            throw new NotImplementedException();
        }

        public void SaveCollection<TInstance>(IEnumerable<TInstance> collection)
            where TInstance : class
        {
            throw new NotImplementedException();
        }

        public void AcceptCollectionChanges<TInstance>(IEnumerable<TInstance> collection)
            where TInstance : class
        {
            throw new NotImplementedException();
        }

        public void MarkCollectionAsDeleted<TInstance>(IEnumerable<TInstance> collection)
            where TInstance : class
        {
            throw new NotImplementedException();
        }

        public void MarkCollectionAsDirty<TInstance>(IEnumerable<TInstance> collection)
            where TInstance : class
        {
            throw new NotImplementedException();
        }

        public void AddCollection<TInstance>(IEnumerable<TInstance> collection)
            where TInstance : class
        {
            throw new NotImplementedException();
        }

        public IEnumerable<TInstance> AttachCollection<TInstance>(IEnumerable<TInstance> collection)
            where TInstance : class
        {
            throw new NotImplementedException();
        }
    }
}
